home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 173_01 / lex.y < prev    next >
Text File  |  1980-01-01  |  18KB  |  748 lines

  1. /*
  2.   HEADER:              CUG  nnn.nn;
  3.   TITLE:               LEX - A Lexical Analyser Generator
  4.   VERSION:             1.1 for IBM-PC
  5.   DATE:                Jan 30, 1985
  6.   DESCRIPTION:         A Lexical Analyser Generator. From UNIX
  7.   KEYWORDS:            Lexical Analyser Generator YACC C PREP
  8.   SYSTEM:              IBM-PC and Compatiables
  9.   FILENAME:            LEX.Y
  10.   WARNINGS:            This program is not for the casual user. It will
  11.                        be useful primarily to expert developers.
  12.                        This file must be processed by YACC with the -d
  13.                        option.
  14.   CRC:                 N/A
  15.   SEE-ALSO:            YACC and PREP
  16.   AUTHORS:             Charles H. Forsyth
  17.                        Scott Guthery 11100 leafwood lane Austin, TX 78750
  18.                        Andrew M. Ward, Jr.  Houston, Texas (Modifications)
  19.   COMPILERS:           LATTICE C
  20.   REFERENCES:          UNIX Systems Manuals -- Lex Manual on distribution disks
  21. */
  22. /*
  23.  * Copyright (c) 1978 Charles H. Forsyth
  24.  *
  25.  *
  26.  * Modified 22-Jun-86 Andrew Ward -- Modified code to compile under Lattice C
  27.  *                                 version 3.0h.  Corrected several errors
  28.  *                                 from the assumption that pointers and
  29.  *                                 integers are the same size.     
  30.  *                                 New debug code for LATTICE C using assert
  31.  *                                 to test for wild pointers.  Using a proper
  32.  *                                 YACC this will produce a ytab.c file that
  33.  *                   does not need hand modification.     
  34.  */
  35.  
  36. /*
  37.  * lex -- grammar/lexical analyser
  38.  */
  39.  
  40. %{
  41. #include <stdio.h>
  42. #include <assert.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include "lexlex.h"
  46.  
  47.  
  48. char    ccl[ (NCHARS+1) / NBPC ];
  49. int  sz_ccl = (NCHARS+1) / NBPC;
  50.     char *yysterm[] = {
  51.        "error",
  52.        "NAME",
  53.        "CCLASS",
  54.        "STRING",
  55.        "CONCAT",
  56.        0     };
  57.     extern char *progname;
  58.     extern char *breakc;
  59.     extern char *ignore;
  60.     extern char *illeg;
  61.     extern int  nlook;
  62.     char *lalloc();
  63.     struct des {
  64.        struct nfa *d_start;
  65.        struct nfa *d_final;
  66.     };
  67.     struct nlist {
  68.        struct  nlist   *nl_next;
  69.        struct  nfa     *nl_base;
  70.        struct  nfa     *nl_end;
  71.        struct  nfa     *nl_start;
  72.        struct  nfa     *nl_final;
  73.        char    *nl_name;
  74.     }
  75.     *nlist;
  76.     extern  int str_len;
  77.     extern  struct  nfa     *nfap;
  78.     extern  struct  nfa     *elem(int, char *);
  79.     extern  struct  des     *newdp(struct nfa *, struct nfa *);
  80.     extern  struct  nlist   *lookup(char *);
  81.     extern int     mapc(int);
  82.     extern int     cclass(void);
  83.     extern void    name(int);
  84.     extern void    action(void);
  85.     extern void    skipstr(int);
  86.     extern void    copycode(void);
  87.     extern void    string(int);
  88.     extern void    copynfa(struct nlist *, struct nfa *, struct des *);
  89.     extern void    spccl(char *, char *, struct des *, char **);
  90.     extern void    unget( int );
  91.     extern void    copy(char *, char *, int);
  92.     extern void    errmsg(char *);
  93.     extern void    yyerror(char *, char *);
  94.     extern void    newcase(int);
  95.     extern void    llactr(void);
  96.     extern void    setline(void);
  97.     extern void    cclprint(char *);
  98.     extern int     yyline;
  99.     %}
  100. %union {
  101.     char   *buff;
  102.     struct nlist *list;
  103.     struct des   *des_ptr;
  104.     struct nfa   *elem_ptr;
  105. }
  106. %term NAME CCLASS STRING CONCAT
  107. %token <buff>  STRING NAME CCLASS
  108. %type <buff> NAME CCLASS
  109. %type <list> namedef name
  110. %type <des_ptr> pattern regexp
  111. %left ';'
  112. %left '='
  113. %left '/'
  114. %left '|'
  115. %left '(' NAME STRING CCLASS
  116. %left CONCAT
  117. %left '*'
  118. %%
  119. %{
  120.     struct nfa *np, *nbase;
  121.     char *cp;
  122.     struct des *dp, *dp1;
  123.     struct trans *tp;
  124.     struct nlist *nl;
  125.     int i, c;
  126.     %}
  127. lexfile:
  128. auxiliary_section translation_section
  129. |
  130.  
  131. ;
  132.  
  133. auxiliary_section:
  134. auxiliaries '%' '%'
  135. |       '%' '%'
  136. ;
  137.  
  138. auxiliaries:
  139. auxiliaries auxiliary
  140. |       auxiliary
  141. ;
  142.  
  143. auxiliary:
  144. namedef '=' regexp ';' ={
  145.     dp = $3;
  146.     nl = $1;
  147.     np = nl->nl_base;
  148.     nl->nl_start = dp->d_start;
  149.     nl->nl_final = dp->d_final;
  150.     nl->nl_end = nfap;
  151. #ifdef DEBUG
  152.     printf("NFA for %s\n", nl->nl_name);
  153.     nfaprint(dp->d_start, nl->nl_base);
  154. #endif
  155.     i = nl->nl_end - nl->nl_base;
  156.     nbase = (struct nfa *)lalloc(i, sizeof(struct nfa), "nfa storage");
  157.     copynfa(nl, nbase, dp);
  158.     nl->nl_start = dp->d_start;
  159.     nl->nl_final = dp->d_final;
  160.     nl->nl_end = nbase+i;
  161.     nl->nl_base = nbase;
  162.     nfap = np;
  163.     spccl(nl->nl_name, "ignore", dp, &ignore);
  164.     spccl(nl->nl_name, "break", dp, &breakc);
  165.     spccl(nl->nl_name, "illegal", dp, &illeg);
  166. }
  167. |       '%' '{'         ={
  168.     copycode();
  169. }
  170. ;
  171.  
  172. namedef:
  173. NAME    ={
  174.     $$ = lookup($1);
  175.     $$->nl_base = nfap;
  176.     if ($$->nl_start)
  177.        yyerror("%s redefined", $$->nl_name);
  178. }
  179. ;
  180.  
  181. name:
  182. NAME    = {
  183.     $$ = lookup($1);
  184. }
  185. ;
  186.  
  187. regexp:
  188. CCLASS = {
  189.     np = elem(CCL, $1);
  190.     $$ = newdp(np, (np->n_succ[0] = elem(FIN, (char *)NULL ) ) );
  191. }
  192. |       STRING ={
  193.     cp = $1;
  194.     if (str_len == 0) {
  195.        np = elem(EPSILON, (char *)NULL );
  196.        $$ = newdp(np, (np->n_succ[0] = elem(FIN, (char *)NULL ) ) );
  197.        /* return(0);*/ /* AMW: the return here appears in error */
  198.        }
  199.     else /* AMW: else stmt added 1 May 1986 $$->d_start added */
  200.        {
  201.        $$->d_start = np = elem(*cp++, (char *)NULL);
  202.        while(--str_len > 0)
  203.            np = np->n_succ[0] = elem(*cp++,(char *)NULL);
  204.        $$ = newdp($$->d_start, ( np->n_succ[0] = elem( FIN, (char *)NULL ) ) );
  205.        }
  206.     }
  207.     |       name    ={
  208.        if ((nl = $1)->nl_end == NULL)
  209.        {
  210.            yyerror("%s not defined", nl->nl_name);
  211.            nl->nl_base = nl->nl_end = elem(FIN, (char *)NULL);
  212.            nl->nl_start = nl->nl_final = nl->nl_base;
  213.        }
  214.        $$ = dp = (struct des *)lalloc(1, sizeof(struct des), "dfa input");
  215.        nbase = nfap;
  216.        i = nl->nl_end - nl->nl_base;
  217.        if ((nfap += i) >= &nfa[MAXNFA]) {
  218.            errmsg("Out of NFA nodes");
  219.            exit(1);
  220.        }
  221.        copynfa(nl, nbase, dp);
  222.     }
  223.     |       regexp '*' ={
  224.        $$ = dp = $1;
  225.        dp->d_start = newnfa(EPSILON, (np = dp->d_start), (struct nfa *)NULL);
  226.        dp->d_final->n_char = EPSILON;
  227.        dp->d_final->n_succ[0] = np;
  228.        dp->d_final->n_succ[1] = np = elem(FIN, (char *)NULL);
  229.        dp->d_start->n_succ[1] = np;
  230.        dp->d_final = np;
  231.     }
  232.     |       regexp '|' regexp ={
  233.        $$ = dp = $1;
  234.        dp->d_start = newnfa(EPSILON, dp->d_start, $3->d_start);
  235.        dp->d_final->n_char = EPSILON;
  236.        dp->d_final = dp->d_final->n_succ[0] = np = elem(FIN, (char *)NULL );
  237.        dp = $3;
  238.        dp->d_final->n_char = EPSILON;
  239.        dp->d_final->n_succ[0] = np;
  240. #ifdef DEBUG
  241.        assert( isdata( (char *)$3, sizeof( struct des) ) );
  242. #endif
  243.        free((char *)$3);
  244.     }
  245.     |       regexp regexp %prec CONCAT ={
  246.        $$ = $1;
  247.        dp = $2;
  248.        np = $$->d_final;
  249.        $$->d_final = dp->d_final;
  250.        np->n_char = dp->d_start->n_char;
  251.        np->n_ccl = dp->d_start->n_ccl;
  252.        np->n_succ[0] = dp->d_start->n_succ[0];
  253.        np->n_succ[1] = dp->d_start->n_succ[1];
  254. #ifdef DEBUG
  255.        assert( isdata( (char *)$2, sizeof( struct nlist) ) );
  256. #endif
  257.        free((char *)$2);
  258.     }
  259.     |       '(' regexp ')' ={
  260.        $$ = $2;
  261.     }
  262.     ;
  263.  
  264. translation_section:
  265.     translations ={
  266.        ending();
  267. trans1:
  268.  
  269.        printf("\nNFA for complete syntax\n");
  270.        printf("state 0\n");
  271.        for (tp = trans; tp < transp; tp++)
  272.            printf("\tepsilon\t%d\n", tp->t_start-nfa);
  273.        for (tp = trans; tp < transp; tp++)
  274.            nfaprint(tp->t_start, nfa);
  275.        ;
  276.     }
  277.     |       ={
  278.        goto trans1;
  279.     }
  280.     ;
  281.  
  282. translations:
  283.     translations translation
  284.        |       llactr translation
  285.        ;
  286.  
  287. llactr:
  288.     ={
  289.        llactr();
  290.     }
  291.     ;
  292.  
  293. translation:
  294.     pattern action ={
  295.        dp = $1;
  296.        newtrans(dp->d_start, dp->d_